package config

import (
	"aqchain/pkg/log"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	"os"
)

// DatabaseConfig 数据库配置
type DatabaseConfig struct {
	DSN         string `json:"dsn"`         // 数据库连接配置
	AutoMigrate bool   `json:"autoMigrate"` // 是否自动创建数据库表
}

// ServerConfig 服务配置
type ServerConfig struct {
	Host string `json:"host"`
	Port string `json:"port"`
}

type EthereumConfig struct {
	Client    ClientConfig    `json:"client"`
	Keystore  KeystoreConfig  `json:"keystore"`
	Contracts ContractsConfig `json:"solidity"`
}

type ContractsConfig struct {
	Item     string `json:"item"`
	Sale     string `json:"sale"`
	Auction  string `json:"auction"`
	License  string `json:"license"`
	Token    string `json:"token"`
	Exchange string `json:"exchange"`
}

type ClientConfig struct {
	RPCAddress string `json:"rpcAddress"`
}

type KeystoreConfig struct {
	PrivateKey string `json:"privateKey"`
}

type LocalConfig struct {
	FileDir        string `json:"fileDir"`
	CertificateDir string `json:"certificateDir"`
	ResourceDir    string `json:"resourceDir"`
	Nat            string `json:"nat"`
}

type AlipayConfig struct {
	PrivateKey       string `json:"privateKey"`
	AppId            string `json:"appId"`
	AliPayRootCert   string `json:"aliPayRootCert"`
	AliPayPublicCert string `json:"aliPayPublicCert"`
	AppPublicCert    string `json:"appPublicCert"`
}

// Config 项目配置
type Config struct {
	Database DatabaseConfig
	Server   ServerConfig
	Ethereum EthereumConfig
	Local    LocalConfig
	Alipay   AlipayConfig
}

func New(configFile string) Config {
	log.Logger.Debug("读取配置文件", zap.String("configFile", configFile))
	var cfg Config
	viper.SetConfigFile(configFile)

	if err := viper.ReadInConfig(); err != nil {
		log.Logger.Panic("配置文件读取错误", zap.String("configFile", configFile), zap.Error(err))
	}
	if err := viper.Unmarshal(&cfg); err != nil {
		if err != nil {
			log.Logger.Panic("配置文件解析错误", zap.String("configFile", configFile), zap.Error(err))
		}
	}

	_, err := os.Stat(cfg.Local.CertificateDir)
	if os.IsNotExist(err) {
		err = os.MkdirAll(cfg.Local.CertificateDir, os.ModePerm)
		if err != nil {
			log.Logger.Panic("配置文件解析错误", zap.String("configFile", cfg.Local.CertificateDir), zap.Error(err))
			return Config{}
		}
	}
	_, err = os.Stat(cfg.Local.FileDir)
	if os.IsNotExist(err) {
		err = os.MkdirAll(cfg.Local.FileDir, os.ModePerm)
		if err != nil {
			log.Logger.Panic("配置文件解析错误", zap.String("configFile", cfg.Local.FileDir), zap.Error(err))
			return Config{}
		}
	}
	return cfg
}
